/* -*- C -*- */

#cpu ppc

#include <stdio.h>
#include <stdlib.h>


typedef int (*pifi)(int);


pifi rpnCompile(char *expr)
{
  insn *code= (insn *)calloc(64, sizeof(insn));
  insn *code2 = code;
  int top= 3;
#ifdef _IBMR2
  code2 = code + 2;
#endif
  #[
	.org	code2
  ]#;


  while (*expr)
    {
      char  buf[32];
      int n ;
      if (sscanf(expr, "%[0-9]%n", buf, &n))
	{
	  expr+= n - 1;
	  if (top == 10)
	    {
	      fprintf(stderr, "expression too complex");
	      exit(0);
	    }
	  ++top;
	  #[
		lis	r(top), atoi(buf)@hi
		ori	r(top), r(top), atoi(buf)@lo
	  ]#;
	}
      else if (*expr == '+')
	#[
	  ! --top;
		add	r(top), r(top), r(top+1)
	]#
      else if (*expr == '-')
	#[
	  ! --top;
		sub	r(top), r(top), r(top+1)
	]#
      else if (*expr == '*')
	#[
	  ! --top;
		mullw	r(top), r(top), r(top+1)
	]#
      else if (*expr == '/')
	#[
	  ! --top;
		divw	r(top), r(top), r(top+1)
	]#
      else
	{
	  fprintf(stderr, "cannot compile: %s\n", expr);
	  abort();
	}
      ++expr;
    }

  if (3 != top)
    {
      fprintf(stderr, "stack error\n");
      abort();
    }

  #[	blr	  ]#;
#ifdef _IBMR2
  {
    long * codeB;
    codeB = (long *) code;
    codeB[0] = (long) code2;
  }
#endif
  iflush(code, hpbcg_asm_pc);
  if ((int)(hpbcg_asm_pc - code) >= 64)
    {
      fprintf(stderr, "expression too complex");
      exit(0);
    }
  return (pifi)code;
}


int main(int argc, char *argv[])
{
  pifi c2f= rpnCompile("9*5/32+");
  pifi f2c= rpnCompile("32-5*9/");
  int i;
  printf("\nC:");
  for (i = 0; i <= 100; i+= 10) printf("%3d ", i);
  printf("\nF:");
  for (i = 0; i <= 100; i+= 10) printf("%3d ", c2f(i));
  printf("\n");
  printf("\nF:");
  for (i = 32; i <= 212; i+= 10) printf("%3d ", i);
  printf("\nC:");
  for (i = 32; i <= 212; i+= 10) printf("%3d ", f2c(i));
  printf("\n");
  return 0;
}
